package com.sunfield.baseframe.http;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.text.TextUtils;
import android.webkit.CookieManager;

import com.sunfield.baseframe.base.BaseActivity;
import com.sunfield.baseframe.base.BaseApplication;
import com.sunfield.baseframe.util.JsonUtil;
import com.sunfield.baseframe.util.MLog;
import com.sunfield.baseframe.util.ToastUtil;
import com.sunfield.baseframe.view.LoadingDialog;

import org.greenrobot.eventbus.EventBus;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Created by wangxl on 2016/10/29.
 */
public class HttpParams {
    /**
     * true：模拟返回值；false：获取真的返回值
     */
    public static boolean mockResult = true;

    private static Handler handler;

    static {
        handler = new Handler();
    }

    String url;
    BaseHttpClient baseHttpClient;
    List<HttpParam> stringParamList;
    List<HttpParam> fileParamList;
    int configKey;
    Object otherForCallback;

    /**
     * 请求使用的Client类名
     */
    String clientClassName;
    /**
     * 请求的方法名
     */
    String clientMethodName;

    /**
     * 是否显示进度弹窗
     */
    boolean isShowDialog;
    /**
     * 是否加锁
     */
    boolean isNeedLock;
    /**
     * 是否提示返回信息
     */
    boolean isToastMsg;
    /**
     * 是否取消loading弹窗
     */
    boolean cancelDialog;
    /**
     * 强制使用MultipartBody(可带文件)
     */
    boolean forceMultipartBody;
    /**
     * 是否自动跳转至登录页
     */
    boolean goToLogin;

    LoadingDialog loadingDialog;

    String resultData;

    HttpParams(String url, BaseHttpClient baseHttpClient) {
        stringParamList = new ArrayList<>();
        fileParamList = new ArrayList<>();
        configKey = -1;
        setUrl(url);
        this.baseHttpClient = baseHttpClient;
        loadingDialog = baseHttpClient.loadingDialog;

        isShowDialog = true;
        isNeedLock = true;
        isToastMsg = true;
        cancelDialog = true;
        forceMultipartBody = false;
        goToLogin = true;
    }

    public HttpParams setShowDialog(boolean showDialog) {
        isShowDialog = showDialog;
        return this;
    }

    public HttpParams setNeedLock(boolean needLock) {
        isNeedLock = needLock;
        return this;
    }

    public HttpParams setToastMsg(boolean toastMsg) {
        isToastMsg = toastMsg;
        return this;
    }

    public HttpParams setUrl(String url) {
        this.url = url;
        return this;
    }

    public HttpParams setConfigKey(int configKey) {
        this.configKey = configKey;
        return this;
    }

    public HttpParams setCancelDialog(boolean cancelDialog) {
        this.cancelDialog = cancelDialog;
        return this;
    }

    public void setClientClassName(String clientClassName) {
        this.clientClassName = clientClassName;
    }

    public void setClientMethodName(String clientMethodName) {
        this.clientMethodName = clientMethodName;
    }

    public HttpParams setOtherForCallback(Object otherForCallback) {
        this.otherForCallback = otherForCallback;
        return this;
    }

    public HttpParams setForceMultipartBody(boolean forceMultipartBody) {
        this.forceMultipartBody = forceMultipartBody;
        return this;
    }

    public HttpParams setGoToLogin(boolean goToLogin) {
        this.goToLogin = goToLogin;
        return this;
    }

    public HttpParams setResult(String resultData) {
        this.resultData = resultData;
        return this;
    }

    /**
     * 添加字符串参数
     *
     * @param key
     * @param value
     */
    public void addParam(String key, String value) {
        stringParamList.add(new HttpParam(key, value));
    }

    /**
     * 添加文件
     *
     * @param key
     * @param value
     */
    public void addFile(String key, String value) {
        fileParamList.add(new HttpParam(key, value));
    }

    public RequestBody createRequestBody() {
        StringBuffer sb = new StringBuffer(url + "?");
        if (!forceMultipartBody && fileParamList.isEmpty()) {
            FormBody.Builder builder = new FormBody.Builder();
            for (HttpParam param : stringParamList) {
                if (param != null && param.key != null && param.value != null) {
                    builder.add(param.key, param.value);
                    sb.append(param.key + "=" + param.value + "&");
                }
            }
            MLog.d("httpParams", sb.toString());
            return builder.build();
        }
        MediaType MEDIA_TYPE_FILE = MediaType.parse("file");
        MultipartBody.Builder builder = new MultipartBody.Builder();
        builder.setType(MultipartBody.FORM);
        for (HttpParam param : stringParamList) {
            if (param != null && param.key != null && param.value != null) {
                builder.addFormDataPart(param.key, param.value);
                sb.append(param.key + "=" + param.value + "&");
            }
        }
        for (HttpParam param : fileParamList) {
            if (param != null && param.key != null && param.value != null) {
                builder.addFormDataPart(param.key, param.value, RequestBody.create(MEDIA_TYPE_FILE, new File(param.value)));
                sb.append(param.key + "=" + param.value + "&");
            }
        }
        MLog.d("httpParams", sb.toString());
        return builder.build();
    }

    public void post() {
        if (isNeedLock) {
            if (baseHttpClient.isLock) {
                return;
            }
            baseHttpClient.isLock = true;
        }
        if (isShowDialog) {
            showDialog();
        }
        //创建OkHttpClient实例
        int connectTime = 10;
        if (mockResult) {
            connectTime = 1;
        }
        OkHttpClient client = new OkHttpClient.Builder().connectTimeout(connectTime, TimeUnit.SECONDS).readTimeout(connectTime, TimeUnit.SECONDS).writeTimeout(connectTime, TimeUnit.SECONDS).build();

        RequestBody requestBody = createRequestBody();
        //构建请求
        HttpHeader httpHeader = HttpHeader.getInstance();

        CookieManager cookieManager = CookieManager.getInstance();

        String cookie = cookieManager.getCookie(url);

        MLog.d("httpParams", "cookie = " + cookie);
        if (cookie == null) {
            cookie = "";
        }

        Request request = new Request.Builder()
                .url(url)//地址
                .post(requestBody)//添加请求体
                .header("cookie", cookie)
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                if (mockResult) {
                    String resultJson = resultData;
                    if (!TextUtils.isEmpty(resultJson)) {
                        MLog.i("httpResult", resultJson);
                        dealResult(new HttpResult(url, resultJson, "", configKey, true, "0", otherForCallback, clientClassName, clientMethodName));
                        return;
                    }
                }
                MLog.e("httpResult", "httpFail:" + (e == null ? "" : (e.getMessage() == null ? "" : e.getMessage())));
                String message = "网络连接失败，请稍后再试";
                dealResult(new HttpResult(url, null, message, configKey, false, "500", otherForCallback, clientClassName, clientMethodName));
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String json = response.body().string();
                MLog.i("httpResult", json);
                boolean isSuccess = JsonUtil.isSuccess(json);
                String message = JsonUtil.GetStringByLevel(json, "msg");
                MLog.d("httpResult", "msg = " + message);
                String statusCode = JsonUtil.GetStringByLevel(json, "status");
                dealResult(new HttpResult(url, json, message, configKey, isSuccess, statusCode, otherForCallback, clientClassName, clientMethodName));
//                if (json.contains("(") && json.contains(")")) {
//                    json = json.substring(json.indexOf("(") + 1, json.lastIndexOf(")"));
//                    json = json.replaceAll("'", "\"");
//                    while (json.contains(",}")) {
//                        json = json.replace(",}", "}");
//                    }
//                    MLog.d("httpResult", json);
//
//                } else {
//                    onFailure(null, null);
//                }
            }
        });
    }

    void showDialog() {
        handler.post(new Runnable() {
            @Override
            public void run() {
                loadingDialog.show();
            }
        });
    }

    void dealResult(final HttpResult httpResult) {
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (!httpResult.isSuccess() || cancelDialog) {
                    loadingDialog.dismiss();
                }

                if (isNeedLock) {
                    baseHttpClient.isLock = false;
                }

                if (!httpResult.isSuccess) {
                    if (isToastMsg) {
                        String errorMsg = httpResult.getMessage();
                        if (TextUtils.isEmpty(errorMsg)) {
                            errorMsg = "网络异常，请稍后尝试";
                        }
                        ToastUtil.toast(errorMsg);
                    }
                    if ("5".equals(JsonUtil.GetStringByLevel(httpResult.getJson(), "status"))) {
                        BaseApplication.getInstance().logout();
                        if (goToLogin) {
                            Class cls = HttpHeader.getInstance().getLoginClass();
                            Context context = baseHttpClient.context;
                            if (cls != null) {
                                Intent intent = new Intent(context, cls);
                                if (context instanceof Activity) {
                                    ((Activity) context).startActivityForResult(intent, BaseActivity.REQUEST_CODE_LOGIN);
                                } else {
                                    context.startActivity(intent);
                                }
                            }
                        }
                    }
                }
                EventBus.getDefault().post(httpResult);
            }
        }, 100 * 3);
    }

    class HttpParam {
        String key;
        String value;

        public HttpParam(String key, String value) {
            this.key = key;
            this.value = value;
        }
    }
}
